package com.sinodata.bsm.common.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>Title: </p>
 * <p>Description: 字符串相关的工具类</p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: ylcxkj.com</p>
 * @author zhaoch
 * @version 1.0b
 */
public class StringUtil {

    /**
     * 字符串替换。
     * @param inStr String 原始字符串
     * @param oldStr String 要替换的内容
     * @param newStr String 替换的新内容
     * @return String 替换之后得到的字符串
     */
    public static String replace(String inStr, String oldStr, String newStr) {
        if (inStr == null || oldStr == null || newStr == null || oldStr.length() == 0) {
            return inStr;
        }
        StringBuilder resultStr = new StringBuilder();
        int pos = -1;
        boolean exitWhile = false;
        try {
            if (inStr != null && !inStr.equals("") && inStr.length() > 0) {
                while (!exitWhile) {
                    pos = inStr.indexOf(oldStr);
                    if (pos > 0) {
                        resultStr.append(inStr.substring(0, pos - 0)).append(newStr);
                        inStr = inStr.substring(pos + oldStr.length());
                    } else if (pos == 0) {
                        resultStr.append(newStr);
                        inStr = inStr.substring(pos + oldStr.length());
                    } else
                        exitWhile = true;
                }
            }
        } catch (Exception e) {
            System.out.println("Replacing string:" + inStr + " error, the exception is:" + e);
        }

        return resultStr + inStr;
    }

    /**
     * 替换首个匹配的字符
     * @param inStr String 要替换的内容
     * @param oldStr String 要替换的内容
     * @param newStr String 替换的新内容
     * @return String 替换之后得到的字符串
     */
    public static String replaceFirst(String inStr, String oldStr, String newStr) {
        if (inStr == null || oldStr == null || newStr == null) {
            return inStr;
        }
        String resultStr = "";
        int pos = -1;
        pos = inStr.indexOf(oldStr);
        if (pos >= 0) {
            resultStr = inStr.substring(0, pos) + newStr + inStr.substring(pos + oldStr.length(), inStr.length());
        }
        return resultStr;
    }

    /**
     * 根据List of String 返回'A','B','C'列表
     * @param list List 存放的List
     * @return String 'A','B','C'的字符串
     */
    @SuppressWarnings("rawtypes")
    public static String convertListToString(List list) {
        if (list == null) {
            return "''";
        }
        java.util.Iterator ir = list.iterator();
        StringBuilder retStr = new StringBuilder();
        while (ir.hasNext()) {
            retStr.append("'").append(ir.next()).append("'").append(",");
        }
        if (retStr.toString().endsWith(","))
            retStr = new StringBuilder(retStr.substring(0, retStr.length() - 1));
        return retStr.toString();
    }

    /**
     * 将str中的"'"替换为"''",
     * 为sql语句执行
     * @param str
     * @return
     */
    public static String replaceForSQL(String str) {
        if (str == null)
            return null;
        return replace(str, "'", "''");
    }

    /**
     * 将字符串按照seperator划分开。如果输入为空或空串,返回null
     * @param s
     * @param seperator
     * @return
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static String[] convertStringToStringArray(String s, String seperator) {
        if (s == null || s.equals(""))
            return null;

        StringTokenizer st = new StringTokenizer(s, seperator);
        Vector vec = new Vector();
        while (st.hasMoreTokens()) {
            vec.addElement(st.nextToken());
        }
        String[] array = new String[vec.size()];
        vec.copyInto(array);
        return array;
    }

    /**
     * 将字符串分割成List
     * @param s String
     * @param seperator String
     * @return List
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static List convertStringToArrayList(String s, String seperator) {
        if (s == null || s.equals(""))
            return null;

        StringTokenizer st = new StringTokenizer(s, seperator);
        Vector vec = new Vector();
        while (st.hasMoreTokens()) {
            vec.addElement(st.nextToken());
        }
        String[] array = new String[vec.size()];
        vec.copyInto(array);
        List list = new ArrayList(array.length);
        for (int i = 0; i < array.length; i++) {
            list.add(i, array[i]);
        }
        return list;

    }

    /**
     * 将字符串以^分割成ArrayList
     * @param s String
     * @return List
     */
    @SuppressWarnings("rawtypes")
    public static List convertStringToArrayList(String s) {
        return convertStringToArrayList(s, "^");
    }

    /**
     * 将List中的字符串以^连接成字符串
     * @param list List
     * @return String
     */
    @SuppressWarnings("rawtypes")
    public static String convertArrayListToString(List list) {
        if (list == null || list.size() == 0)
            return null;

        StringBuilder s = new StringBuilder((String) list.get(0));
        for (int i = 1; i < list.size(); i++) {
            s.append("^").append((String) list.get(i));
        }
        return s.toString();
    }

    /**
     * 整型数组转成以 deli 分隔的字符串。
     * @param arr
     * @param deli
     * @return
     * @post $result!=null
     */
    public static String intArrToString(int[] arr, String deli) {
        if (arr == null) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < arr.length; i++) {
            sb.append(arr[i]);
            if (i != arr.length - 1) {
                sb.append(deli);
            }
        }
        return sb.toString();
    }

    /**
     *  以 deli 分隔的字符串转成整型数组。
     * @param s
     * @param deli
     * @return
     * @post $result!=null
     */
    public static int[] stringToIntArr(String s, String deli) {
        try {
            StringTokenizer tokens = new StringTokenizer(s, deli);
            int[] arr = new int[tokens.countTokens()];
            int idx = 0;
            while (tokens.hasMoreTokens()) {
                String token = tokens.nextToken();
                int intVal = Integer.parseInt(token);
                arr[idx] = intVal;
                idx++;
            }
            return arr;
        } catch (Exception ex) {
            return new int[0];
        }
    }

    /**
     *  以 deli 分隔的字符串转成整型数组。
     * 如果s为null,或者s中的字符转换为数字过程出错,则返回float[0]
     * @param s
     * @param deli
     * @return
     * @post $result!=null
     */
    public static float[] stringToFloatArr(String s, String deli) {
        try {
            StringTokenizer tokens = new StringTokenizer(s, deli);
            float[] arr = new float[tokens.countTokens()];
            int idx = 0;
            while (tokens.hasMoreTokens()) {
                String token = tokens.nextToken();
                float floatVal = Float.parseFloat(token);
                arr[idx] = floatVal;
                idx++;
            }
            return arr;
        } catch (Exception ex) {
            return new float[0];
        }
    }

    /**
     * 将"aa^bb^cc"这样的字符串转换为
     * 'aa','bb','cc'
     * @author chzhao
     * 2003-03-06
     */
    public static String getInSQL(String str) {
        if (str == null)
            return null;
        java.util.StringTokenizer st = new java.util.StringTokenizer(str, "^");
        String tmpStr = "";
        String retStr = "";
        while (st.hasMoreTokens()) {
            tmpStr = st.nextToken();
            tmpStr = "'" + tmpStr + "'";
            retStr += tmpStr + ",";
        }
        if (retStr != null && retStr.endsWith(","))
            retStr = retStr.substring(0, retStr.length() - 1);
        return retStr;
    }

    /**
     * 将一个Collection中的每个对象的字符串形式用^连接起来
     *
     * @param values 可以包含任何对象
     * @return 转换后的字符串
     * @author lvkai 2003/1/17
     */
    @SuppressWarnings("rawtypes")
    public static String convertCollectionToString(Collection values) {
        if (values == null || values.size() == 0)
            return "";

        Iterator iterator = values.iterator();
        StringBuffer sb = new StringBuffer(iterator.next().toString());
        while (iterator.hasNext()) {
            sb.append("^");
            sb.append(iterator.next());
        }
        return sb.toString();
    }

    /**
     * 将以^分割的字符串进行排序
     * @param s String
     * @return String
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static String sortStringList(String s) {
        if (s == null || s.equals(""))
            return s;
        List slist = convertStringToArrayList(s);
        Collections.sort(slist);
        //log(convertArrayListToString(slist));
        return convertArrayListToString(slist);
    }

    /**
     * log
     * @param s String
     */
    public static void log(String s) {
        System.out.println("" + s);
    }

    /**
     * 判断一个字符串是否为空,当字符串为null或者""时
     * @param s String
     * @return boolean
     */
    public static boolean isEmpty(String s) {
        if (s == null || s.equals(""))
            return true;
        else
            return false;
    }

    //  public static String[] splitStr(String srcStr, String seperator) {
    //    String[] strArray;
    //    try {
    //      StringTokenizer strToken = new StringTokenizer(srcStr, seperator);
    //      int count = strToken.countTokens();
    //      strArray = new String[count];
    //      // modify by credible_zhang at 2004.07.31:当计数为0的时候返回一个空的字符串
    //      if(count == 0) return new String[]{""};
    //      // modify end.
    //      int i = 0;
    //      while (strToken.hasMoreElements()) {
    //        strArray[i] = strToken.nextToken();
    //        i++;
    //      }
    //      return strArray;
    //    }
    //    catch (Exception e) {
    //      strArray = new String[] {
    //          "err"};
    //      return strArray;
    //    }
    //  }
    //
    /**
     * 以分隔符将字符串分割成数组
     * @param srcStr String
     * @param seperator String
     * @return String[]
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static String[] splitStr(String srcStr, String seperator) {
        //        String[] strArray = null;
        List strArrayList = new ArrayList();
        // 当分隔符seperator为空的时候仅返回一个包含所有字符串的字符串数组
        if (seperator == null || seperator.equals(""))
            return new String[] { srcStr };
        // 当被分割字符串为空的时候返回一个仅包含"err"的字符串数组
        if (srcStr == null)
            return new String[0];
        int sepLen = seperator.length();
        int start = 0;
        int end = srcStr.indexOf(seperator, start);
        while (end != -1) {
            String temp = srcStr.substring(start, end);
            strArrayList.add(temp);
            start = end + sepLen;
            end = srcStr.indexOf(seperator, start);
        }
        String temp = srcStr.substring(start, srcStr.length());
        strArrayList.add(temp);
        return (String[]) strArrayList.toArray(new String[strArrayList.size()]);
    }

    /**
     * 分隔字符串为数组，并且每个元素都去掉前面和后面的空格。
     * @param str
     * @return
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static String[] splitStrWithTrim(String srcStr, String seperator) {
        //        String[] strArray = null;
        List strArrayList = new ArrayList();
        // 当分隔符seperator为空的时候仅返回一个包含所有字符串的字符串数组
        if (seperator == null || seperator.equals(""))
            return new String[] { srcStr };
        // 当被分割字符串为空的时候返回一个仅包含"err"的字符串数组
        if (srcStr == null)
            return new String[0];
        int sepLen = seperator.length();
        int start = 0;
        int end = srcStr.indexOf(seperator, start);
        while (end != -1) {
            String temp = srcStr.substring(start, end).trim();
            temp = trimLeft(temp);
            strArrayList.add(temp);
            start = end + sepLen;
            end = srcStr.indexOf(seperator, start);
        }
        String temp = srcStr.substring(start, srcStr.length()).trim();
        temp = trimLeft(temp);
        strArrayList.add(temp);
        return (String[]) strArrayList.toArray(new String[strArrayList.size()]);
    }

    /**
     * 以空格将str分割成数组
     * 当str为null时返回零长度的数组
     * @param str
     * @return
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static String[] splitStr(String str) {
        if (str == null) {
            return new String[0];
        }
        StringTokenizer st = new StringTokenizer(str, " ");
        List list = new ArrayList();
        while (st.hasMoreTokens()) {
            list.add(st.nextToken().trim());
        }
        return (String[]) list.toArray(new String[list.size()]);
    }

    /**
     * 以长度分割字符串,分割成数组
     * @param content StringBuffer
     * @param length int
     * @return String[]
     */
    public static String[] splitStr(StringBuffer content, int length) {
        if (content == null) {
            return null;
        } else if (content.length() <= length) {
            return new String[] { content.toString() };
        } else {
            int arraySize = (int) Math.ceil(content.length() / (float) length);
            String[] strings = new String[arraySize];
            for (int i = 0; i < arraySize; i++) {
                int start = i * length;
                int end = (i + 1) * length <= content.length() ? (i + 1) * length : content.length();
                strings[i] = content.substring(start, end);
            }
            return strings;
        }
    }

    /**
     * 把字符串数组合并成以 seprator 分隔的一个字符串。
     * @param srcArr
     * @param seperator
     * @return String
     */
    public static String mergStr(String[] srcArr, String seperator) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; srcArr != null && i < srcArr.length; i++) {
            sb.append(srcArr[i]);
            if (i != srcArr.length - 1) {
                sb.append(seperator);
            }
        }
        return sb.toString();
    }

    /**
     * 字符转换 ISO TO GBK
     * @param str
     * @return
     */
    public static String iso2gbk(String str) {
        String value = "";
        if (str == null || str.length() == 0)
            return "";
        try {
            value = new String(str.getBytes("ISO8859_1"), "GBK");
        } catch (Exception e) {
            return null;
        }
        return value;

    }

    /**
     * 字符转换 GBK TO ISO
     * @param str
     * @return
     */
    public static String gbk2iso(String str) {
        String value = "";
        if (str == null || str.length() == 0)
            return "";
        try {
            value = new String(str.getBytes("GBK"), "ISO8859_1");
        } catch (Exception e) {
            return null;
        }
        return value;

    }

    /**
     * 删除字符串中的空格
     * @param s String
     * @return String
     */
    public static String removeSpaces(String s) {
        if (s == null) {
            return s;
        }
        StringBuffer sb = new StringBuffer();
        int length = s.length();
        for (int i = 0; i < length; i++) {
            char c = s.charAt(i);
            if (!Character.isWhitespace(c)) {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 把字符串中的空白字符用其他字符替换
     * @param s
     * @param replace
     * @return
     */
    public static String removeSpaces(String s, String replace) {
        if (s == null) {
            return s;
        }
        StringBuffer sb = new StringBuffer();
        int length = s.length();
        for (int i = 0; i < length; i++) {
            char c = s.charAt(i);
            if (!Character.isWhitespace(c)) {
                sb.append(c);
            } else {
                sb.append(replace);
            }
        }
        return sb.toString();
    }

    /**
     * 计算一个字符串中包含子字符串的个数
     * @param str String
     * @param sub String
     * @return int
     */
    public static int containSubstring(String str, String sub) {
        if (str == null || sub == null) {
            return 0;
        }
        int count = 0;
        boolean run = true;
        do {
            int index = str.indexOf(sub);
            if (index == -1) {
                run = false;
            } else {
                count++;
                str = str.substring(index + sub.length(), str.length());
            }
        } while (run);
        return count;
    }

    /**
     * 比较两个数组是否相等
     * @param a
     * @param b
     * @return
     */
    public static boolean compareStringArray(String[] a, String[] b) {
        if (a == null || b == null) {
            return !((a == null) ^ (b == null));
        }
        if (a.length != b.length) {
            return false;
        }
        for (int i = 0; i < a.length; i++) {
            if (a[i] == null || b[i] == null) {
                if ((a[i] == null) ^ (b[i] == null)) {
                    return false;
                }
            } else if (!a[i].equals(b[i])) {
                return false;
            }
        }
        return true;
    }

    /**
     * 根据指定的下标判断两个数组是否相等，相等返回true，否则返回false
     * @param a 用于比较的第一个数组
     * @param b 用于比较的第二个数组
     * @param c 用于比较的下标数组
     * @return true/false
     */
    public static boolean compareStringArray(String[] a, String[] b, int[] c) {
        if (c == null || c.length == 0) {
            return true;
        }
        if (a == null || b == null || a.length < c.length || b.length < c.length) {
            return false;
        }
        for (int i = 0; i < c.length; i++) {
            if ((a[i] == null) && (b[i] == null)) {
                continue;
            }
            if ((a[i] == null) || (b[i] == null)) {
                return false;
            }
            if (!a[i].equals(b[i])) {
                return false;
            }
        }
        return true;
    }

    /**
     * 对一个字符表示的数值做截取操作
     * @param s
     * @param decimalDigits
     * @return
     * @author wangmh
     */
    public static String truncNumberString(String s, int decimalDigits) {
        if (s == null || decimalDigits < 0) {
            return s;
        } else {
            s = s.trim();
        }
        int pointIdx = s.indexOf(".");
        if (s.length() == 0 || pointIdx == -1) {
            return s;
        }
        int endIdx = s.length();
        if (decimalDigits == 0) {
            endIdx = Math.min(endIdx, pointIdx);
        } else {
            endIdx = Math.min(endIdx, pointIdx + decimalDigits + 1);
        }
        return s.substring(0, endIdx);
    }

    /**
     * 将str根据begin,end拆分为多个字符串数组
     *
     * @param str
     * @param b - begin String
     * @param e - end String
     * @return
     */
    public static String[] getValueFromString(String str, String b, String e) {
        int size = containSubstring(str, b);
        String[] ret = new String[size];
        int index = 0;
        int t;
        int step = b.length();
        for (int i = 0; i < size; i++) {
            index = str.indexOf(b, index);
            t = str.indexOf(e, index);
            ret[i] = str.substring((index = index + step), t);
        }
        return ret;
    }

    /**
     * 判断一个字符串是否可以正确转换成数字类型
     * @param str String
     * @return boolean
     */
    public static boolean isIntNumber(String str) {
        if (str == null) {
            return false;
        } else {
            str = str.trim();
            for (int i = 0, length = str.length(); i < length; i++) {
                if (!Character.isDigit(str.charAt(i))) {
                    return false;
                }
            }
            return true;
        }
    }

    /**
     * 判断String中内容是否为数字类型,允许且只允许存在一个'.'
     * @param str String
     * @return boolean
     */
    public static boolean isDoubleNumber(String str) {
        int p = 0;
        if (str == null) {
            return false;
        } else {
            str = str.trim();
            for (int i = 0, length = str.length(); i < length; i++) {
                if (!Character.isDigit(str.charAt(i))) {
                    if (str.charAt(i) != '.')
                        return false;
                    else
                        p++;
                }
            }
            if (p > 1)
                return false;
            return true;
        }
    }

    //  public static void main(String[] args){
    //    String[] ret = getValueFromString("<123><acd>x<fff> <6666>","<",">");
    //    for(int i = 0; i < ret.length; i++){
    //      System.out.println(ret[i]);
    //    }
    //  }

    /**
     * 删除左边连续的空格
     * @param value
     * @return
     */
    public static String trimLeft(String value) {
        String result = value;
        if (result == null)
            return result;
        char ch[] = result.toCharArray();
        int index = -1;
        for (int i = 0; i < ch.length; i++) {
            if (Character.isWhitespace(ch[i])) {
                index = i;
            } else {
                break;
            }
        }
        if (index != -1) {
            result = result.substring(index + 1);
        }
        return result;
    }

    /**
     * 将已知的或不知格式的String转换成double
     * 转换的格式为:"19873","198.73","1,987.3"...
     * 如果将不属于以上格式的字符串或将带有非数字的字符串送入来转换Double会产生
     * java.long.NumberFormatException.
     * 在此方法中做的是将上述几种格式的字符串转换成Double.parserDouble()方法可以识别的
     * 格式.例如:安装了中文AIX的ps中的pcpu值为"0,2"即0.2
     * @param value String
     * @return double
     */
    public static double parserDouble(String value) {
        String temp = "0.0";
        if (value != null) {
            int commaNum = containSubstring(value, ",");
            int dotNum = containSubstring(value, ".");
            if (commaNum >= 1 && dotNum == 1)
                temp = value.replaceAll(",", "");
            else if (commaNum == 1 && dotNum == 0) {
                temp = value.replaceAll(",", ".");
            } else
                temp = value;
        }
        return Double.parseDouble(temp);
    }

    /**
     * 以非科学计数法格式将数字转化为字符串
     * @param d double
     * @return String
     */
    public static String getString(double d) {
        String str = "";
        double max = 1000000d;
        int cnt = 0;
        while (d >= max) {
            d /= max;
            cnt++;
        }
        str = String.valueOf(d);
        int index = str.indexOf('.');
        String s = str.substring(0, index);
        int l = str.length();
        int idx = index + 1 + cnt * 6;
        if (l > idx) {
            s += str.substring(index + 1, idx);
            s += ".";
            s += str.substring(index + 1 + cnt * 6);
        } else {
            s += str.substring(index + 1);
            for (int i = 0; i < idx - l; i++) {
                s += "0";
            }
        }
        if (s.endsWith(".0")) {
            s = s.substring(0, s.length() - 2);
        }
        return s;
    }

    /**
     * 截取byte长度在length之内的字符串
     * @param str String
     * @param length int
     * @return String
     */
    public static String interceptByByteLength(String str, int length) {
        int bytes;
        while ((bytes = str.getBytes().length) > length) {
            int l = (int) Math.ceil((bytes - length) / 2.0);
            str = str.substring(0, str.length() - l);
        }
        return str;
    }

    /**
     * 例如：
     * originalString = "(.1.3.6.1.2.1.2.2.1.0+1.3.6.1.2.1.2.2.1.1)*.1.3.6.1.2.1.2.2.1.2/1.3.6.1.2.1.2.2.1.3"
     * 
     * regex = "\\.?(\\d+\\.)+\\d+" 
     * 
     * 输出结果：($1+$2)*$3/$4
     * 
     * @param originalString 
     *            原始待替换的字符串
     * @param regex          
     *            要求的正则表达式
     * @return
     */
    public static String replaceAllByRegex(String originalString, String regex) {
        String testedString = originalString;
        StringBuffer buffer = new StringBuffer(regex);
        buffer.insert(0, ".*").append(".*");
        int i = 1;
        while (testedString.matches(buffer.toString())) {
            testedString = testedString.replaceFirst(regex, "\\$" + i++);
        }
        return testedString;
    }

    /**
     * 
     * 例如：
     * originalString = "(.1.3.6.1.2.1.2.2.1.0+1.3.6.1.2.1.2.2.1.1)*.1.3.6.1.2.1.2.2.1.2/1.3.6.1.2.1.2.2.1.3"
     * 
     * regex = "\\.?(\\d+\\.)+\\d+"
     * 
     * Map<String, String> map = getAllByRegex(testedString, regex);
     * Set<String> keySet = map.keySet();
     * for (String s : keySet) {
     *      System.out.println("key:[" + s + "];\tvalue:[" + map.get(s) + "]");
     * }
     * 
     * 输出结果：
     * 
     * key:[$4]; value:[1.3.6.1.2.1.2.2.1.3]
     * key:[$1]; value:[.1.3.6.1.2.1.2.2.1.0]
     * key:[$3]; value:[.1.3.6.1.2.1.2.2.1.2]
     * key:[$2]; value:[1.3.6.1.2.1.2.2.1.1]
     * key:[sum]; value:[($1+$2)*$3/$4]
     * 
     * @param originalString
     *            原始待的字符串
     * @param regex
     *            要求的正则表达式
     * @return
     */
    public static Map<String, String> getAllByRegex(String originalString, String regex) {
        Map<String, String> map = new HashMap<String, String>();
        String testedString = originalString;

        StringBuffer buffer = new StringBuffer(regex);
        buffer.insert(0, ".*").append(".*");

        Pattern pattern = Pattern.compile(regex);

        int i = 1;
        while (testedString.matches(buffer.toString())) {
            Matcher matcher = pattern.matcher(testedString);
            if (matcher.find()) {
                String key = "$" + i++;
                String value = matcher.group(0);
                map.put(key, value);
                testedString = testedString.replaceFirst(regex, "\\" + key);
            }

        }
        map.put("sum", testedString);
        return map;
    }

    /**
     * 测试
     * @param args String[]
     */
    public static void main(String[] args) {
        String str = "aaa中文1234";
        System.out.println("" + interceptByByteLength(str, 4));
    }

}
